const fs = require('fs');
const path = require('path');

const args = process.argv.splice(2);
const tableName = args[0];
const moduleName = toHump(tableName)
const fileName = toLine(tableName)
const ModuleName = firstToUpper(moduleName)
let root = '../src/modules/';
// let root = './modules/';
const HOST = process.env.HOST || "localhost";
const USER = process.env.USER || "mallAdmin";
const PASSWORD = process.env.PASSWORD || "1qaz!QAZ";
const DATABASE = process.env.DATABASE || "mall";

// 获取controller模板
let controllerTemplate = fs.readFileSync(path.join(__dirname, './template.controller'), 'utf8');
let moduleTemplate = fs.readFileSync(path.join(__dirname, './template.module'), 'utf8');
let serviceTemplate = fs.readFileSync(path.join(__dirname, './template.service'), 'utf8');



//读取文件，并且替换文件中指定的字符串
let replaceFile = function (filePath, sourceRegx, targetStr) {
    fs.readFile(filePath, function (err, data) {
        if (err) {
            return err;
        }
        let str = data.toString();
        str = str.replace(sourceRegx, targetStr);
        fs.writeFile(filePath, str, function (err) {
            if (err) return err;
        });
    });
}
// 导入模型
let appModulePath = path.join(__dirname, './../src/app.module.ts')
fs.readFile(appModulePath, function (err, data) {
    if (err) {
        return err;
    }
    let str = data.toString();
    str = str.replace(/import location/g, `import location
import { ${ModuleName}Module } from './modules/${moduleName}/${fileName}.module';
`).replace(/module location/g, `module location
        ${ModuleName}Module,`)
    fs.writeFile(appModulePath, str, function (err) {
        if (err) return err;
    });
});


// let appModule = fs.readFileSync(appModulePath, 'utf8');
// let moduleContent = appModule.replace(/import location/g, `import location\n
// import { ${ModuleName}Module } from './modules/${moduleName}/${fileName}.module';
// `).replace(/module location/g, `module location\n
// ${ModuleName},
// `)

buildModule(controllerTemplate, moduleName, ".controller.ts");
buildModule(moduleTemplate, moduleName, ".module.ts");
buildModule(serviceTemplate, moduleName, ".service.ts");
generate_entity(tableName, moduleName, ".entity.ts")

function buildModule(template, moduleName, fileSuffix) {

    let content = template
        .replace(/moduleName/g, moduleName)
        .replace(/ModuleName/g, ModuleName)
        .replace(/fileName/g, fileName);
    let targetDirPath = path.join(__dirname, root, moduleName);
    let targetFilePath = path.join(__dirname, root, moduleName, toLine(tableName) + fileSuffix);
    if (!fs.existsSync(targetDirPath)) {
        fs.mkdirSync(targetDirPath);
        console.log('The ' + targetDirPath + ' folder has been created!');
    }
    if (!fs.existsSync(targetFilePath)) {
        fs.writeFile(targetFilePath, content, (err) => {
            if (err) throw err;
            console.log('The ' + targetFilePath + ' has been created!');
        });
    } else {
        console.error('error!\n' + targetFilePath + ' has already been existed!');
    }
}

function firstToUpper(str) {
    return str.trim().replace(str[0], str[0].toUpperCase());
}

function toHump(name) {
    let newName = name.toLowerCase();
    let arr = newName.split('');
    for (let index in arr) {
        if (arr[index] == '_') {
            let i = parseInt(index);
            arr[i + 1] = arr[i + 1].toUpperCase();
        }
    }
    return arr.join('').replace(/_/g, '');
}

function toLine(name) {
    let newName = name.toLowerCase();
    let arr = newName.split('');
    for (let index in arr) {
        if (arr[index] == '_') {
            let i = parseInt(index);
            arr[i + 1] = arr[i + 1];
        }
    }
    return arr.join('').replace(/_/g, '-');
}


function generate_entity(tableName, moduleName, fileSuffix) {
    var mysql = require('mysql');
    var connection = mysql.createConnection({
        host: HOST,
        user: USER,
        password: PASSWORD,
        database: DATABASE
    });


    connection.connect();

    connection.query(`show full columns from \`${tableName}\``, function (error, results, fields) {
        if (error) throw error;
        if (results.length == 0) return
        let targetDirPath = path.join(__dirname, root, moduleName);
        let targetFilePath = path.join(__dirname, root, moduleName, toLine(tableName) + fileSuffix);
        if (!fs.existsSync(targetDirPath)) {
            fs.mkdirSync(targetDirPath);
            console.log('The ' + targetDirPath + ' folder has been created!');
        }

        let head = `import {Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn} from 'typeorm';\n
import {ApiProperty} from "@nestjs/swagger";

@Entity({name:'${tableName}'})
export class ${ModuleName}Entity{`

        fs.writeFileSync(targetFilePath, head, {
            flag: 'a'
        });

        results.forEach(item => {
            let fieldName = item["Field"]
            let fieldType = item["Type"]
            let comment = item["Comment"]
            console.log(fieldName, fieldType, comment)
            let typeName = ""
            if (fieldType.indexOf("int") != -1 || fieldType.indexOf("decimal") != -1) {
                typeName = "number"
            } else if (fieldType.indexOf("varchar") != -1 || fieldType.indexOf("text") != -1) {
                typeName = "string"
            } else if (fieldType.indexOf("datetime") != -1) {
                typeName = "Date"
            }
            let line = ""
            if (fieldName === "id") {
                line += "\n\n    @PrimaryGeneratedColumn()"
            } else if (fieldName === "created_time") {
                line += "\n    @CreateDateColumn()"
            } else if (fieldName === "updated_time") {
                line += "\n    @UpdateDateColumn()"
            } else {
                line += "\n    @Column()"
            }
            line += `\n    @ApiProperty({description: \'${comment}\'})\n` +
                `    ${toHump(fieldName)}: ${typeName}\n`
            // console.log(line)

            fs.writeFileSync(targetFilePath, line, {
                flag: 'a'
            });
        })

        fs.writeFileSync(targetFilePath, "\n}", {
            flag: 'a'
        });
    });
}

